#include <napi.h>
#include <thread>
#include <iostream>

// 异步任务，处理数据并返回 Promise 结果
void ProcessDataInThread(Napi::ThreadSafeFunction tsfn, char* data, size_t length) {
    try {
        if (data != nullptr) {
            // 模拟数据处理
            std::cout << "Processing data in thread..." << std::endl;
            bool success = length > 0;

            // 在线程中处理完成后，通过 tsfn 传递结果到主线程
            tsfn.BlockingCall([success](Napi::Env env, Napi::Function jsCallback) {
                // 这里在主线程中执行
                if (success) {
                    jsCallback.Call({Napi::Boolean::New(env, true)});
                } else {
                    jsCallback.Call({Napi::Boolean::New(env, false)});
                }
            });
        } else {
            // 如果数据为 null，则返回失败
            tsfn.BlockingCall([](Napi::Env env, Napi::Function jsCallback) {
                jsCallback.Call({Napi::Boolean::New(env, false)});
            });
        }
    } catch (...) {
        // 捕获所有异常并返回失败
        tsfn.BlockingCall([](Napi::Env env, Napi::Function jsCallback) {
            jsCallback.Call({Napi::Boolean::New(env, false)});
        });
    }

    // 完成数据处理，关闭 ThreadSafeFunction
    tsfn.Release();
}

// 导出函数：接收 buffer 并返回 Promise
Napi::Value StartProcessing(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 1) {
        throw Napi::Error::New(env, "Processing requires a buffer argument");
    }

    // 获取 Buffer 数据
    Napi::Buffer<char> buffer = info[0].As<Napi::Buffer<char>>();
    char* data = buffer.Data();
    size_t length = buffer.Length();
    std::cout << "Received data length: " << length << std::endl;

    // 创建一个 Promise
    Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);

    // 创建线程安全函数，用于在后台线程中传递数据
    Napi::ThreadSafeFunction tsfn = Napi::ThreadSafeFunction::New(
        env,
        Napi::Function::New(env, [deferred](const Napi::CallbackInfo& info) {
            // JS 回调函数，接收线程处理的结果
            Napi::Env env = info.Env();
            bool result = info[0].As<Napi::Boolean>().Value();

            if (result) {
                deferred.Resolve(Napi::Boolean::New(env, true));
            } else {
                deferred.Reject(Napi::String::New(env, "Processing failed"));
            }
        }),
        "ThreadSafeFunction",  // 线程安全函数的名字
        0,                     // 无限队列
        1                      // 线程数量
    );

    // 在后台线程中处理数据
    std::thread([tsfn, data, length]() mutable {
        ProcessDataInThread(tsfn, data, length);
    }).detach();

    // 返回 Promise 对象给 JavaScript
    return deferred.Promise();
}

// 模块初始化
Napi::Object Init(Napi::Env env, Napi::Object exports) {
    exports.Set(Napi::String::New(env, "startProcessing"), Napi::Function::New(env, StartProcessing));
    return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)